package com.mengshu.token.helper;

import com.mengshu.token.api.LoginUser;
import com.mengshu.token.api.LoginService;
import com.mengshu.token.consts.TokenConsts;
import com.mengshu.token.storage.UserStorage;
import com.mengshu.token.utils.ThreadLocalUtils;
import com.mengshu.token.utils.TokenConfigUtils;
import lombok.RequiredArgsConstructor;

import java.util.Set;

@RequiredArgsConstructor
public class LoginHelper implements LoginService {

    protected final TokenConfigUtils tokenConfigUtils;

    protected final UserStorage userStorage;

    protected final static String THREAD_LOCAL_TOKEN = TokenConsts.THREAD_LOCAL_TOKEN;

    public String login(String token, LoginUser loginUser) {
        return login(token, null, loginUser, null);
    }

    public String login(String token, String platform, LoginUser loginUser) {
        return login(token, platform, loginUser, null);
    }

    private String login(String token, String platform, LoginUser loginUser, Long timeout) {
        final String tokenString = getTokenString(token, platform);
        long storageTimeout = timeout == null ? getTimeout(tokenString) : timeout;
        if (storageTimeout <= 0) {
            userStorage.set(tokenString, loginUser);
        } else {
            userStorage.set(tokenString, loginUser, storageTimeout);
        }
        return tokenString;
    }

    public void logout() {
        final String tokenString = (String) ThreadLocalUtils.get(THREAD_LOCAL_TOKEN);
        if (tokenString != null) {
            // 删除ThreadLocal中的token信息
            ThreadLocalUtils.clear(tokenString);

            // 删除
            userStorage.del(tokenString);
        }
    }

    public long logout(long userId) {
        return logout(userId, getDefaultPlatform());
    }

    public long logout(long userId, String platform) {
        Set<String> tokenStrings = userStorage.pattern(getTokenPrefix(platform) + TokenConfigUtils.SPLIT + "*");
        long counts = 0;
        for (String tokenString : tokenStrings) {
            final LoginUser loginUser = userStorage.get(tokenString);
            if (loginUser != null && loginUser.getId() != null && loginUser.getId().compareTo(userId) == 0) {
                userStorage.del(tokenString);
                counts++;
            }
        }
        return counts;
    }

    @Override
    public LoginUser getLoginUser() {
        return getLoginUser((String) ThreadLocalUtils.get(THREAD_LOCAL_TOKEN));
    }

    public LoginUser getLoginUser(String tokenString) {
        if (tokenString == null) {
            return null;
        }
        long timeout = getTimeout(tokenString);
        if (timeout <= 0) {
            return userStorage.get(tokenString);
        } else {
            return userStorage.get(tokenString, timeout);
        }
    }

    @Override
    public Long getLoginUserId() {
        final LoginUser loginUser = getLoginUser();
        return loginUser == null ? null : loginUser.getId();
    }

    @Override
    public String getLoginUserName() {
        final LoginUser loginUser = getLoginUser();
        return loginUser == null ? null : loginUser.getName();
    }

    private String getTokenString(String token, String platform) {
        return tokenConfigUtils.getTokenString(token, platform);
    }

    private long getTimeout(String tokenString) {
        return tokenConfigUtils.getTimeout(tokenString);
    }

    private String getDefaultPlatform() {
        return tokenConfigUtils.getDefaultPlatform();
    }

    private String getTokenPrefix(String platform) {
        return tokenConfigUtils.getTokenPrefix(platform);
    }
}
